"""
自定义一个django文件存储后端，来实现构建完整图片url。
"""

# 导入django默认的存储后端
from django.core.files.storage import Storage
from django.conf import settings
from fdfs_client.client import Fdfs_client

# FastDFSStorage自定义的存储后端
class FastDFSStorage(Storage):

    def __init__(self, fdfs_base_url=None):
        self.fdfs_base_url = fdfs_base_url or settings.FDFS_BASE_URL

    # 功能：打开django本地文件
    def _open(self, name, mode='rb'):
        pass

    # 功能：实现文件保存 —— Django项目二中我们需要补充代码实现文件上传fdfs
    def _save(self, name, content, max_length=None):
        # 参数：name是文件名称；content是文件对象；max_length文件体积，None表示按照实际文件大小读取

        # TODO: 上传图片二进制字节数据到fdfs，获取文件的索引id
        conn = Fdfs_client(settings.FDFS_CONF_PATH)

        ret = conn.upload_by_buffer(content.read())

        if ret['Status'] != 'Upload successed.':
            # 上传失败
            raise serializers.ValidationError('文件上传失败')

        file_id = ret['Remote file_id']

        # TODO: 在存储后端的_save方法中，返回文件id --> 该返回值就是将来存储在mysql中的文件索引id
        return file_id



    # 功能：判断前端传递的文件是否已经存在 —— 存在则无需重复保存(不会调用self._save)；不存在则需要保存(调用self._save)
    def exists(self, name):
        # 参数：name是文件名称(文件的索引id)
        # 该函数中，本来是需要通过文件名称name判定django本地文件是否存在；
        # 但是，现在我们的文件数据是保存到fdfs中的，此处无需判定;

        # 返回值True表示本地文件存在不会调用_save；
        # 返回值False表示本地文件不存在，则调用_save;
        # 注意：我们当前业务，不会文件是否存在进行判定，通过返回False调用_save实现上传fdfs
        return False

    # 功能：构造图片文件的完整url
    def url(self, name):
        # 参数name：图片链接的路径部分(存储在mysql中文件索引id)
        return self.fdfs_base_url + name